/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 * Created on 04.08.2004
 * @author Andreas Prlic
 *
 */



package org.biojava.services.das.registry ;


import org.xml.sax.*;
import javax.xml.parsers.*;


import org.biojava.dasobert.dasregistry.DasCoordinateSystem;
import org.biojava.utils.ClassTools;
import org.w3c.dom.*;
import java.util.HashMap ;
import java.util.Map ;
import java.io.InputStream ;
import java.io.IOException ;
import java.net.URL;

/**
 * A class that reads the configuration file of the registry
 */
public final class RegistryConfiguration {
	public static final String CONFIG_FILE = "dasregistrycfg.xml";

	static Map configuration ;



	static {
		try {
			readConfiguration(CONFIG_FILE);
		} catch ( Exception e ) {
			e.printStackTrace();
			configuration = new HashMap();
		}

	}


	/** read the configuration for this registration service from a file. set the interal configuration. 
	 * To retrieve it use getConfiguration(); @see getConfiguration()
	 *
	 */
	private static void readConfiguration(String filename) 
	throws Exception
	{
		
//		make sure we use the Xerces XML parser..
//		System.out.println("setting default parser to Xerces");
//		System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
//		"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
//		System.setProperty("javax.xml.parsers.SAXParserFactory",
//		"org.apache.xerces.jaxp.SAXParserFactoryImpl");
//		
//		
//		System.out.println("reading configuration from " + filename);
		configuration = new HashMap();
		
		//System.out.println( RegistryConfiguration.class.getClassLoader());

		ClassLoader cl = ClassTools.getClassLoader(RegistryConfiguration.class);

		InputStream fs = cl.getResourceAsStream(filename);

		if ( fs == null) {
			throw new IOException("did not find config file "+ filename );
		}
		InputSource is = new InputSource(fs);

		DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();

		Element cfgDoc = parser.parse(is).getDocumentElement();

		// first child is dasregistry
		Node chld = cfgDoc.getFirstChild();

		if (chld instanceof Element) {
			Element el1 = (Element) chld ;
			if ( ! (el1.getTagName().equals("dasregistry"))) {
				throw new Exception("configuration file is not a das registry configuration file!");
			}
		}

		while (chld != null) {
			if (chld instanceof Element) {
				Element echld = (Element) chld;
				//System.out.println(echld.getTagName());
				if ( echld.getTagName().equals("dasclient")){
					parseDasClientTree(chld);

				} else if ( echld.getTagName().equals("passkey")){
					String passnumber = echld.getAttribute("number");
					configuration.put("passkey", passnumber);

				}
				else if (echld.getTagName().equals("sendmailhost")) {

					String sendmailhost = echld.getAttribute("name");

					configuration.put("sendmailhost",sendmailhost);
				} else if ( echld.getTagName().equals("serveradmin")){
					String serveradmin = echld.getAttribute("email");
					configuration.put("serveradmin",serveradmin);
				}
				/*
		else if ( echld.getTagName().equals("dbconn")){

		String connstr = echld.getAttribute("connstring");
		    String dbuser = echld.getAttribute("user");
		     String dbpass = echld.getAttribute("password");
		    String dbdriver = echld.getAttribute("dbdriver");
		    HashMap dbconn = new HashMap();
		    dbconn.put("dbConnStr",connstr);
		    dbconn.put("dbUser",dbuser);
		    dbconn.put("dbPass",dbpass);
		    dbconn.put("dbDriver",dbdriver);
		    //System.out.println("got DB connection " + dbconn);
		    this.configuration.put("dbConn",dbconn);
		    }*/
				else if ( echld.getTagName().equals("jspconfig")){
					String dassource = echld.getAttribute("dassource");
					configuration.put("jsp_dassource",dassource);
					String dascoordsys = echld.getAttribute("dascoordinatesystem");
					configuration.put("jsp_dascoordinatesystem",dascoordsys);
				}
				else if ( echld.getTagName().equals("dasdirectory")){
					String name = echld.getAttribute("name");
					configuration.put("dasdirectory",name);
				}
				else if ( echld.getTagName().equals("webservice")){
					String name = echld.getAttribute("location");
					configuration.put("webserviceLocation",name);
				}
				else if ( echld.getTagName().equals("remindermail")){
					String name = echld.getAttribute("frequency");
					configuration.put("mailfrequency",name);
				}
				else if ( echld.getTagName().equals("parentregistry")){
					String name = echld.getAttribute("location");
					configuration.put("parentregistry",name);
				} 
				else if ( echld.getTagName().equals("proxyHost")){
					String name = echld.getAttribute("host");
					configuration.put("proxyHost",name);
					System.setProperty("proxySet","true");
					System.setProperty("http.proxyHost",name);
					System.setProperty("proxyHost",name);
				}
				else if ( echld.getTagName().equals("proxyPort")){
					String name = echld.getAttribute("port");
					configuration.put("proxyPort",name);
					System.setProperty("http.proxyPort",name);
					System.setProperty("proxyPort",name);
				} 
				else if ( echld.getTagName().equals("idPrefix")){
					String prefix = echld.getAttribute("prefix");
					configuration.put("idPrefix",prefix);
					//System.out.println("found idPrefix " + prefix);		    
				}
				else if (echld.getTagName().equals("cacheParent")) {
					String value = echld.getAttribute("value");
					Map cachMap = new HashMap();
					cachMap.put("value",value);
					String freq = echld.getAttribute("frequency");
					cachMap.put("frequency",freq);
					configuration.put("cacheParent",cachMap);
				} 
				else if ( echld.getTagName().equals("autoValidate")){
					Map valiMap = new HashMap();
					String value = echld.getAttribute("value");
					valiMap.put("value",value);
					String freq = echld.getAttribute("frequency");
					valiMap.put("frequency",freq);
					configuration.put("autoValidate",valiMap);
				}
				else if ( echld.getTagName().equals("relaxNgPath1_5")){
					
					String value = echld.getAttribute("basePath");
					configuration.put("relaxNgPath1_5",value);
				}
				else if ( echld.getTagName().equals("relaxNgPath1_6")){
					;
					String value = echld.getAttribute("basePath");
					
					configuration.put("relaxNgPath1_6",value);
				}
			}
			chld = chld.getNextSibling();
		}	
		
		
		//PropertyConfigurator.configure("logConfig.txt");
		//System.out.println("finished reading config");
		//System.out.println(this.configuration);
	}

	private static void parseDasClientTree(Node chld) {
		//System.out.println("parseDasClientTree");


		if (chld instanceof Element) {

			Element echld = (Element) chld;
			//System.out.println(echld);
			if ( echld.getTagName().equals("dasclient")){
				DasClient dasclient = new DasClient();
				// we are at dasclient element
				String clientName = echld.getAttribute("name");		
				String homepage   = echld.getAttribute("homepage");

				//System.out.println("clientName " + clientName);
				dasclient.setName(clientName);
				try {
					URL home = new URL(homepage);
					dasclient.setHomepage(home);
				} catch (Exception e) {
					System.out.println("could not set homepage URL " + e.getMessage());
				}

				Node subchld = echld.getFirstChild();

				while ( subchld != null ) {

					if ( subchld instanceof Element ) {
						Element subele = (Element) subchld;
						if ( subele.getTagName().equals("coordSys")){
							String coordName   = subele.getAttribute("name");
							String activateUrl = subele.getAttribute("activate");
							//System.out.println(coordName + " " + activateUrl);
							
							/*Map coordMap = new HashMap();
							coordMap.put("name",coordName);
							coordMap.put("activate",activateUrl);
							dasclient.addCoordSysMap(coordMap);
							*/
							AutoActivation aa = new AutoActivation();
							aa.setActivationURL(activateUrl);
							aa.setClient(dasclient);
							DasCoordinateSystem cs = DasCoordinateSystem.fromString(coordName);
							aa.setCoordSys(cs);	
							AutoActivation[] aas = (AutoActivation[]) configuration.get("AutoActivation");
							if ( aas == null){
								aas = new AutoActivation[1];
								aas[0] = aa;
							} else {
								AutoActivation[] naas = new AutoActivation[aas.length+1];
								for (int i = 0 ; i < aas.length ;i++){
									naas[i] = aas[i];
								}
								naas[aas.length] = aa;
								aas = naas;
							}
							//System.out.println("adding AA " + aa.getActivationURL());
							configuration.put("AutoActivation", aas);
							
						}
						else if ( subele.getTagName().equals("displayIcon")){
							String iconPath = subele.getAttribute("path");
							//System.out.println(iconPath);
							dasclient.setIconPath(iconPath);
						}
					}
					subchld = subchld.getNextSibling();
				}


				// add to existing DasClients ...
				DasClient[] clients = (DasClient[])configuration.get("DASClients");
				int length = 0;
				DasClient[] newclients = new DasClient[1] ;
				newclients[0] = dasclient;
				if (clients != null) {
					length = clients.length;
					newclients = new DasClient[length + 1] ;
					for ( int i=0; i < clients.length ; i++ ) {
						newclients[i] = clients[i];
					}
					newclients[length] = dasclient;
				}

				configuration.put("DASClients",newclients);


			}
		}


	}


	/** returns the configuration as a Map 
	 * @return the configuration as a Map 
	 * */
	public Map getConfiguration(){

		return configuration;
	}

}
